package cz.muni.fi.hauntedhouses.dao.impl;

import cz.muni.fi.hauntedhouses.dao.GhostDAO;
import cz.muni.fi.hauntedhouses.entity.Ghost;
import cz.muni.fi.hauntedhouses.to.GhostTO;
import cz.muni.fi.hauntedhouses.util.GhostUtil;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;

/**
 *
 * @author Andrea Vasekova, 325181
 */
@Repository
public class GhostDAOImpl implements GhostDAO {
    
    @PersistenceContext
    private EntityManager em;
    
    public GhostDAOImpl() {
    }
    
    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        this.em = em;
    }
    
    @Override
    public void create(GhostTO ghostTO) {
        if (ghostTO == null) {
            throw new IllegalArgumentException("Given ghost cannot be null");
        }
        
        Ghost ghost = GhostUtil.TOToEntity(ghostTO);
        em.persist(ghost);
        ghostTO.setId(ghost.getId());
    }

    @Override
    public GhostTO get(Long id) {
        if ((id == null) || (id < 1)) {
            throw new IllegalArgumentException("Invalid ID");
        }
        Ghost ghost = em.find(Ghost.class, id);
        GhostTO ghostTO = GhostUtil.entityToTO(ghost);
        return ghostTO;
    }

    @Override
    public void update(GhostTO ghostTO) {
        if (ghostTO == null) {
            throw new IllegalArgumentException("Given ghost cannot be null");
        }
        if (ghostTO.getId() == null) {
            create(ghostTO);
        } else {
            Ghost ghost = GhostUtil.TOToEntity(ghostTO);
            em.merge(ghost);
        }
    }

    @Override
    public void remove(GhostTO ghostTO) {
        if (ghostTO == null) {
            throw new IllegalArgumentException("Given ghost cannot be null");
        }
        if ((ghostTO.getId() != null) && (ghostTO.getId() >= 1)) {
            Ghost savedGhost = em.find(Ghost.class, ghostTO.getId());
            if (savedGhost != null) {
                em.remove(savedGhost);
            }
        }
    }

    @Override
    public List<GhostTO> findAll() {
        List<Ghost> ghosts = em.createQuery("SELECT g FROM Ghost g").getResultList();
        
        return GhostUtil.listToTO(ghosts);
    }

    @Override
    public List<GhostTO> findByName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Name to search for cannot be null");
        }
        Query query = em.createQuery("SELECT g FROM Ghost g WHERE g.name LIKE :name", Ghost.class);
        query.setParameter("name", name + "%");
        List<Ghost> ghosts = query.getResultList();
        
        return GhostUtil.listToTO(ghosts);
    }
    
}
